import axios, { type AxiosResponse, type AxiosRequestConfig } from 'axios';
import qs from 'qs';
import { nanoid } from 'nanoid';
import AxiosAdapter from './axios-adapter/index';

export const TOKEN_NAME = 'bfcToken';

let message = null;
export type HttpConfig = AxiosRequestConfig & {
    /** 错误适配器 */
    errorAdapter?: (data: unknown) => unknown;

    /** 是否跳过错误处理 */
    skipError?: boolean;
    headers?: {
        'recycloud-token'?: string;
    };
};

function handleLogin() {
    if (!window.location.pathname.includes('/login')) {
        // 登录重定向
        window.location.href = '/login';
    }
}

const headers = {};
const defaultConfig: HttpConfig = {
    method: 'POST',
    headers,
    timeout: 1000 * 60,
    withCredentials: true,
    skipError: false,
    baseURL: '',
};
const adapters = [
    {
        name: 'EnDecryptAdapter',
        options: {
            getIsEncrypt: async () => {
                try {
                    const response = await fetch('/api/sysapi/queryEncrySwitch', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            domain: 'recycloud-web-ui',
                            timeStamp: Date.now(),
                            transId: nanoid(),
                            signMethod: 'MD5',
                            apiVersion: 'v1.0',
                            data: {},
                        }),
                    });
                    const { data } = await response.json();
                    return data?.reqEncrySwitch === 'ON';
                } catch (err) {
                    console.error(err);
                    throw err;
                }
            },
        },
    },
];
const myAxios = new AxiosAdapter(axios, defaultConfig).init(adapters);

const errorMessages = {
    400: '请求错误',
    401: '未授权，请登录',
    403: '拒绝访问',
    404: '请求地址出错',
    408: '请求超时',
    500: '服务器内部错误',
    501: '服务未实现',
    502: '网关错误',
    503: '服务不可用',
    504: '网关超时',
    505: 'HTTP版本不受支持',
};

function getErrMessage(errResponse: AxiosResponse): string {
    return errorMessages[errResponse?.status] || '';
}

function handleError(msg?: string) {
    message?.error(msg || '服务器错误，请稍后再试~');
    console.log(msg);
}

const downloadFile = (res: any, resolve: (res?: any) => void, reject: (res?: any) => void) => {
    if (!res) {
        reject(new Error('数据不存在'));
        return;
    }
    const fileName = res.headers['content-disposition']?.split?.('=')?.[1] || '下载文件.xls';
    const blob = new Blob([res.data], {
        type: res.headers?.['content-type'],
    });
    const url = window.URL.createObjectURL(blob);
    const aLink = document.createElement('a');
    aLink.style.display = 'none';
    aLink.href = url;
    aLink.setAttribute('download', decodeURI(fileName));
    document.body.appendChild(aLink);
    aLink.click();
    document.body.removeChild(aLink);
    window.URL.revokeObjectURL(url);
    resolve(true);
};

function createAxios<T, D>(
    options: typeof defaultConfig = {},
    token: any = localStorage?.getItem(TOKEN_NAME),
): Promise<D> {
    const finalConfig: typeof defaultConfig = {
        ...defaultConfig,
        ...options,
        headers: {
            ...defaultConfig.headers,
            ...options?.headers,
        },
    };
    return new Promise((resolve, reject) => {
        const currentMethod = finalConfig.method?.toLocaleLowerCase();
        // const token = localStorage.getItem(TOKEN_NAME);
        if (!finalConfig.headers) {
            finalConfig.headers = {};
        }
        if (token) {
            const curToken = JSON.parse(token);
            finalConfig.headers['recycloud-annotate-appId'] = '1774973799448580096';
            finalConfig.headers['recycloud-annotate-token'] = curToken.state.token;
            finalConfig.headers['recycloud-annotate-tenant'] = curToken.state.currentTenant;
        }
        finalConfig.headers['Client-Type'] = 'web';
        if (finalConfig.headers['Content-Type'] === 'multipart/form-data') {
            finalConfig.data = qs.stringify(
                {
                    domain: 'recycloud-web-ui',
                    timeStamp: Date.now(),
                    transId: nanoid(),
                    signMethod: 'MD5',
                    apiVersion: 'v1.0',
                    file: finalConfig.data,
                    data: JSON.stringify({}),
                },
                { arrayFormat: 'brackets' },
            );
            delete finalConfig.headers['Content-Type'];
        } else if (currentMethod === 'get') {
            finalConfig.params = {
                domain: 'recycloud-web-ui',
                timeStamp: Date.now(),
                transId: nanoid(),
                signMethod: 'MD5',
                apiVersion: 'v1.0',
                data: finalConfig.data,
            };
            finalConfig.paramsSerializer = (params) => qs.stringify(params, { arrayFormat: 'brackets' });
            delete finalConfig.data;
        } else if (currentMethod === 'post') {
            finalConfig.data = {
                domain: 'recycloud-web-ui',
                timeStamp: new Date().getTime(),
                transId: nanoid(),
                signMethod: 'MD5',
                apiVersion: 'v1.0',
                data: finalConfig.data ?? {},
            };
        }

        // 请求
        myAxios
            .request<
                T | any,
                {
                    status?: string;
                    config?: any;
                    data: {
                        rspCode: string;
                        rspDesc: string;
                        data: D;
                    };
                } & D
            >(finalConfig)
            .then((response) => {
                const res = response.data;
                if (response?.config?.responseType === 'blob') {
                    // 下载文件
                    downloadFile(response, resolve, reject);
                } else if (response?.config?.responseType === 'arraybuffer') {
                    return resolve(response);
                } else {
                    const { rspCode, code } = res;
                    const isSuccess = code === '000000' || rspCode === '000000';

                    if (!isSuccess) {
                        // 未登录
                        if (
                            // 报废车
                            ['100045', '999984'].includes(rspCode) ||
                            // 运营中台
                            ['100040'].includes(code)
                        ) {
                            handleLogin();
                            console.log('isSuccess', isSuccess);
                        }
                        if (!finalConfig.skipError) {
                            handleError(res?.rspDesc);
                        }
                        reject(res);
                    } else {
                        resolve(res.data);
                    }
                }
            })
            .catch((error) => {
                console.error(error);
                if (error?.response?.status === 401) {
                    console.log('error', error);
                    // 未登录
                    handleLogin();
                }
                const errorMsg = getErrMessage(error.response);
                if (errorMsg) {
                    handleError(errorMsg);
                }
                reject(error);
            });
    });
}

export const getAxios = (messageInstance: any) => {
    message = messageInstance;
    return createAxios;
};
export default createAxios;
